package com.example.knowledgeget1.ChatCommon.Service;

import com.example.knowledgeget1.ChatCommon.Entity.NodeType;
import com.example.knowledgeget1.ChatCommon.Repository.NodeTypeRepository;
import com.example.knowledgeget1.KnowtCommon.Entity.KnowStatus;
import com.example.knowledgeget1.KnowtCommon.Entity.Knowin;
import com.example.knowledgeget1.KnowtCommon.Entity.KnowinId;
import com.example.knowledgeget1.KnowtCommon.Repository.KnowStatusRepository;
import com.example.knowledgeget1.KnowtCommon.Repository.KnowinRepository;
import com.example.knowledgeget1.KnowtCommon.Repository.StudyRepository;
import com.example.knowledgeget1.KnowtCommon.Service.CourseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Semaphore;

@Service
public class NodeTypeService {

    private final NodeTypeRepository nodeTypeRepository;
    private final KnowinRepository knowinRepository;
    @Autowired
    private CourseService courseService;
    @Autowired
    private ChatService chatService;
    @Autowired
    private TaskExecutor taskExecutor2;
    @Autowired
    private KnowStatusRepository knowStatusRepository;
    @Autowired
    private StudyRepository studyRepository;
    private final Semaphore semaphore = new Semaphore(10); // 限制并发调用10

    @Autowired
    public NodeTypeService(NodeTypeRepository nodeTypeRepository, KnowinRepository knowinRepository) {
        this.nodeTypeRepository = nodeTypeRepository;
        this.knowinRepository = knowinRepository;
    }

    // 根据知识点ID列表获取发布知识点列表
    public List<NodeType> getNodeTypesByKnowIdsRelease(List<Long> knowIds) {
        return nodeTypeRepository.findByIsReleaseTrueAndIdIn(knowIds);
    }

    // 根据知识点ID列表获取知识点列表
    public List<NodeType> getNodeTypesByKnowIds(List<Long> knowIds) {
        return nodeTypeRepository.findByIdIn(knowIds);
    }

    // 获取所有知识点类型
    public List<NodeType> getAllNodeTypes() {
        return nodeTypeRepository.findAll();
    }

    // 根据编号获取知识点类型
    public NodeType getNodeTypeById(String id) {
        return nodeTypeRepository.findById(id).orElse(null);
    }

    // 保存知识点类型
    public NodeType saveNodeType(NodeType nodeType) {
        return nodeTypeRepository.save(nodeType);
    }

    // 根据name删除知识点
    public void deleteNodeType(String name) {
        nodeTypeRepository.deleteByName(name);
    }

    // 根据名称查找知识点类型
    public NodeType getNodeTypeByName(String name) {
        return nodeTypeRepository.findByName(name);
    }

 // 更新节点
    public NodeType updateNodeType(NodeType nodeType) {
        return nodeTypeRepository.save(nodeType);
    }
    //获取所有知识点
    public List<NodeType> findAll(){
    	return nodeTypeRepository.findAll();
    }
    //获取所有未被构造的知识点
    public List<NodeType> findAllNotBuild(){
    	return nodeTypeRepository.findAllNotBuild();
    }
    //将构造后的知识点的isBuild属性更新被true
    public List<NodeType> updateBuild(List<NodeType> lists) {
    	for(int i=0;i<lists.size();i++) {
    		lists.get(i).setIsBuild(true);
    		nodeTypeRepository.save(lists.get(i));
    	}
    	return lists;
    }

    //根据id修改知识点为已构筑
    public void updateIsBuildById(String id) {
        nodeTypeRepository.updateIsBuildById(id);
    }

    public void updateIsUnBuildById(String id) {
        nodeTypeRepository.updateIsNotBuildById(id);
    }

    // 根据知识点名称列表添加知识点
    public List<NodeType> addNodeTypesFromCourse(Long courseId, List<String> knowledgeNames) {
        // 获取课程名字
        String courseName = courseService.getCourseById(courseId).getCourseName();
        Optional<NodeType> maxIdNode = nodeTypeRepository.findTopByOrderByIdDesc();
        Long newId = maxIdNode.map(NodeType::getId).orElse(0L) + 1;

        List<NodeType> existingNodeTypes = new ArrayList<>();

        for (String knowledgeName : knowledgeNames) {
            NodeType existingNodeType = nodeTypeRepository.findByName(knowledgeName);
            NodeType newNodeType = new NodeType();
            if (existingNodeType == null) {
                newNodeType.setId(newId++);
                newNodeType.setName(knowledgeName);
                newNodeType.setHasPreNode(false);
                newNodeType.setIsMain(false);
                newNodeType.setIsBranch(false);
                newNodeType.setIsBuild(false);
                newNodeType.setIsRelease(false);
                nodeTypeRepository.save(newNodeType);

                KnowinId knowinId = new KnowinId(courseId, newNodeType.getId());
                Knowin knowin = new Knowin();
                knowin.setId(knowinId);
                knowinRepository.save(knowin);
                CompletableFuture.runAsync(() -> {
                    try {
                        semaphore.acquire(); // 等待信号量获取许可
                        chatService.chat(courseName, String.valueOf(newNodeType.getId()), knowledgeName);
                    } catch (InterruptedException | IOException e) {
                        Thread.currentThread().interrupt();
                    } finally {
                        semaphore.release(); // 释放信号量
                    }
                }, taskExecutor2);
            } else {
                existingNodeTypes.add(existingNodeType);
            }
        }
        return existingNodeTypes;
    }

    // 发布知识点
    public List<NodeType> addNodeTypesFromCourseRelease(@RequestBody Map<String, Object> request) {
        Long courseId = Long.parseLong(request.get("courseId").toString());
        List<Map<String, String>> knowledgeList = (List<Map<String, String>>) request.get("knowledgeList");
        List<Long> studentIds = studyRepository.findStudentIdsByCourseId(courseId);
        List<KnowStatus> statusesToSave = new ArrayList<>();
        List<String> knowledgeNames = knowledgeList.stream()
                .map(map -> map.get("name"))
                .toList();
        List<NodeType> failNodeTypes = new ArrayList<>();
        for (String knowledgeName : knowledgeNames) {
            NodeType nodeType = nodeTypeRepository.findByName(knowledgeName);
            if (nodeType.getIsBuild()){
                nodeType.setIsRelease(true);
                nodeTypeRepository.save(nodeType);
                // 为该课程每个学生和新发布的知识点创建未学习状态
                for (Long studentId : studentIds) {
                    KnowStatus knowStatus = new KnowStatus(studentId, nodeType.getId(), false); // 初始化为未学习状态
                    statusesToSave.add(knowStatus);
                }
            }else{
                failNodeTypes.add(nodeType);
            }
        }
        // 批量保存学习状态
        knowStatusRepository.saveAll(statusesToSave);
        return failNodeTypes;
    }
}
